package com.xuge.common.jwt;


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.xuge.common.exception.EException;
import com.xuge.pojo.UserInfoEntity;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * jwt由三部分组成header payload sign
 */
@Component
public class JWTUtils {
//    private static Long EXPIRE_TIME = 7 * 24 * 3600L;
    //过期时间
    final private static Long EXPIRE_TIME = 60000L;
    //过期时间用于刷新token
    final private static Long LONG_EXPIRE_TIME = 30*24*60*60L;

    final private static String SIGN = "fangxu1205";

    final private static Map<String, Object> headMap = new HashMap<>();

    @Autowired
    private  RedisTemplate redisTemplate ;

    static {
        headMap.put("alg", "HS256");
        headMap.put("typ", "JWT");
    }

    /**
     * 生成token
     * @param userInfoEntity
     * @return
     */
    public  String createToken(UserInfoEntity userInfoEntity) {
        if (userInfoEntity != null && userInfoEntity.getId() > 0
                && StringUtils.isNotBlank(userInfoEntity.getName())) {
            String token = JWT.create().withHeader(headMap)
                    .withClaim("userId", userInfoEntity.getId())
                    .withClaim("userName", userInfoEntity.getName())
                    .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRE_TIME))
                    .sign(Algorithm.HMAC256(SIGN));

            String redisToken = JWT.create().withClaim("userId", userInfoEntity.getId())
                    .withClaim("userName", userInfoEntity.getName())
                    .withExpiresAt(new Date(System.currentTimeMillis()+LONG_EXPIRE_TIME))
                    .sign(Algorithm.HMAC256(SIGN));
            redisTemplate.opsForValue().set(token,redisToken,LONG_EXPIRE_TIME, TimeUnit.SECONDS);
            return token;
        }
        return null;
    }

    /**
     * 解析token
     * @param token
     * @return
     */
    public  DecodedJWT parseToken(String token){
        DecodedJWT jwt = null;
        if (StringUtils.isBlank(token)){
            return jwt;
        }
        try {
            JWTVerifier build = JWT.require(Algorithm.HMAC256(SIGN)).build();
            return build.verify(token);
        }catch (TokenExpiredException e){
            throw e;
        }catch (Exception e) {
            //打印日志
            System.out.println("token解析错误");
            throw e;
        }
    }

    /**
     * 获取登录用户信息
     * @param token
     * @return
     */
    public  UserInfoEntity getUserInfo(String token){
        DecodedJWT decodedJWT = parseToken(token);
        //DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        if (decodedJWT!=null){
            Map<String, Claim> claims = decodedJWT.getClaims();
            userInfoEntity.setId(claims.get("userId").asLong());
            userInfoEntity.setName(claims.get("userName").asString());
        }
        return userInfoEntity;
    }


    private String refreshToken(String token){
        //首先
        String o = (String) redisTemplate.opsForValue().get(token);
        if (StringUtils.isNotBlank(o)){
            UserInfoEntity userInfo = getUserInfo(o);
            return createToken(userInfo);
        }else{
            throw new EException("token失效 请重新登录");
        }
    }
}
